import requests
import json
from datetime import datetime
from typing import Dict, Any, Optional, Union


def fetch_json_data(
    url: str,
    headers: Optional[Dict[str, str]] = None,
    params: Optional[Dict[str, Any]] = None,
    timeout: Optional[int] = 30,
    encoding: Optional[str] = None,
    data: Optional[str] = "data",
):
    """
    获取并解析JSON数据的通用函数

    Args:
        url: 要请求的URL
        headers: 请求头信息
        params: URL参数
        timeout: 请求超时时间（秒）
        encoding: 响应内容的编码格式，默认为None，自动检测
        data: 解析JSON数据的键名，默认为"data"，为None时返回整个JSON对象

    Returns:
        解析后的JSON数据

    Raises:
        requests.exceptions.RequestException: 请求失败时抛出
        json.JSONDecodeError: JSON解析失败时抛出
        KeyError: 指定的键不存在时抛出
    """
    try:
        response = requests.get(url, headers=headers, params=params, timeout=timeout)

        response.raise_for_status()
        if encoding:
            response.encoding = encoding
        else:
            response.encoding = response.apparent_encoding

        json_data = json.loads(response.text)
        if data is None:
            return json_data
        return json_data[data]
    except requests.exceptions.RequestException as e:
        print("请求失败", e)
        raise
    except (json.JSONDecodeError, KeyError) as e:
        print("数据解析失败:", e)
        raise


def fetch_webpage(
    url: str,
    headers: Optional[Dict[str, str]] = None,
    params: Optional[Dict[str, Any]] = None,
    timeout: Optional[int] = 30,
    encoding: Optional[str] = None,
):
    """获取网页内容

    Parameters:
        url: 要请求的URL
        headers: 请求头信息
        params: URL参数
        timeout: 请求超时时间（秒）
        encoding: 响应内容的编码格式，默认为None，自动检测


    Returns:
        爬取后的网页内容

    Raises:
        requests.exceptions.RequestException: 请求失败时抛出
    """
    try:
        response = requests.get(url, headers=headers, params=params,timeout=timeout)

        response.raise_for_status()
        if encoding:
            response.encoding = encoding
        else:
            response.encoding = response.apparent_encoding

        return response.text
    except requests.exceptions.RequestException as e:
        print("请求失败", e)
        raise


def parse_timestamp(
    timestamp: Union[int, str], unit: str = "s", format_str: str = "%Y-%m-%d %H:%M"
) -> str:
    """
    解析时间戳为特定规格的时间格式

    Args:
        timestamp: 时间戳（整数或字符串形式）
        unit: 时间戳单位，'s'表示秒，'ms'表示毫秒
        format_str: 输出的日期时间格式

    Returns:
        格式化的时间字符串
    """
    if not timestamp:
        return ""

    if isinstance(timestamp, str):
        timestamp = int(timestamp)
    
    if timestamp < 0:
        return ""
    
    if unit == "ms":
        timestamp = timestamp / 1000

    dt_object = datetime.fromtimestamp(timestamp)
    return dt_object.strftime(format_str)
